﻿using SQLiteSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using YunLuPos.Entity;
using YunLuPos.Entity.Constant;

namespace YunLuPos.DB.Service
{
    public class SaleOrderGoodsService
    {
        private log4net.ILog logger = log4net.LogManager.GetLogger(typeof(SaleOrderGoodsService));

        public object SaleOrderPriceSource { get; private set; }


        /**
         * 为订单添加商品重新汇总主表结果
         * price 外部价格
         * amount 外部金额用于生鲜称重传入金额
         * */
        public SaleOrder addGoods(SaleOrder order,Goods goods,Double count = 1 ,
                    Double price = Double.NaN,GoodsPriceSource priceSource = GoodsPriceSource.NORM,
                    String promCode = null,Double amount = Double.NaN,Boolean forceOuterPrice = false)
        {
            if(goods.salePrice < 0)
            {
                return order;
            }
            DBLocker.setLocker();
            using (SqlSugarClient db = SugarDao.GetInstance())
            {
                SaleOrderGoods orderGoods = new SaleOrderGoods();
                orderGoods.orderId = order.orderId;
                orderGoods.orderCode = order.orderCode;
                orderGoods.cliqueCode = order.cliqueCode;
                orderGoods.branchCode = order.branchCode;
                orderGoods.goodsCode = goods.goodsCode;
                orderGoods.goodsName = goods.goodsName;
                orderGoods.specs = goods.specs;
                orderGoods.unit = goods.unitName;
                orderGoods.barCode = goods.barCode;
                orderGoods.packCount = goods.unitCount;
                orderGoods.goodsCount = count;
                orderGoods.price = goods.salePrice;
                orderGoods.disPrice = goods.salePrice;
                orderGoods.disCount = 100;
                orderGoods.promCode = promCode;
                if (!Double.NaN.Equals(price))
                {
                    orderGoods.disPrice = price;
                }

                if (forceOuterPrice)
                {
                    //强制使用外部价格
                    orderGoods.price = price;
                    orderGoods.disPrice = price;
                }

                orderGoods.realAmount = Math.Round(orderGoods.goodsCount * orderGoods.price,2);
                orderGoods.payAmount = Math.Round( orderGoods.goodsCount * orderGoods.disPrice,2);
                //考虑传入金额 修复生鲜码传入金额汇算bug开始
                if (!Double.NaN.Equals(amount))
                {
                    orderGoods.payAmount = amount;
                }
                ////考虑传入金额 修复生鲜码传入金额汇算结束
                orderGoods.disAmount = (orderGoods.realAmount - orderGoods.payAmount);
                orderGoods.priceSource = priceSource.ToString();

                db.BeginTran();
                try
                {
                    Int64 result = (Int64)db.Insert<SaleOrderGoods>(orderGoods);
                    if (result <= 0)
                    {
                        return null;
                    }
                    result = db.ExecuteCommand(@"UPDATE SaleOrder SET 
		            goodsCount = (select sum(goodsCount) from SaleOrderGoods where orderId = @o1 GROUP BY orderId),
		            realAmount = (select sum(realAmount) from SaleOrderGoods where orderId = @o2 GROUP BY orderId),
		            payAmount = (select sum(payAmount) from SaleOrderGoods where orderId = @o3 GROUP BY orderId),
		            disAmount = (select sum(disAmount) from SaleOrderGoods where orderId = @o4 GROUP BY orderId)
                    WHERE orderId = @o5", new
                    {
                        o1 = order.orderId,
                        o2 = order.orderId,
                        o3 = order.orderId,
                        o4 = order.orderId,
                        o5 = order.orderId
                    });

                    if (result > 0)
                    {
                        db.CommitTran();
                        return order;
                    }
                    else
                    {
                        db.RollbackTran();
                    }
                }
                catch(Exception ex)
                {
                    db.RollbackTran();
                    logger.Error(ex);
                }
                finally
                {
                    DBLocker.release();
                }
            }
            return null;
        }


        /***
         * 删除单品并重新汇算
         * */
        public Boolean delGoods(SaleOrderGoods goods)
        {
            DBLocker.setLocker();
            using (SqlSugarClient db = SugarDao.GetInstance())
            {
                try
                {
                    db.BeginTran();
                    Boolean b = db.Delete<SaleOrderGoods>(it => it.id == goods.id);
                    if (b)
                    {
                        Int64 result = db.ExecuteCommand(@"UPDATE SaleOrder SET 
		                goodsCount = (select sum(goodsCount) from SaleOrderGoods where orderId = @o1 GROUP BY orderId),
		                realAmount = (select sum(realAmount) from SaleOrderGoods where orderId = @o2 GROUP BY orderId),
		                payAmount = (select sum(payAmount) from SaleOrderGoods where orderId = @o3 GROUP BY orderId),
		                disAmount = (select sum(disAmount) from SaleOrderGoods where orderId = @o4 GROUP BY orderId)
                        WHERE orderId = @o5", new
                            {
                                o1 = goods.orderId,
                                o2 = goods.orderId,
                                o3 = goods.orderId,
                                o4 = goods.orderId,
                                o5 = goods.orderId
                            });
                        if (result > 0)
                        {
                            //单品删除如果存在支付记录进行清空
                            List<SaleOrderAccount> a = db.Queryable<SaleOrderAccount>().Where(it => it.orderCode == goods.orderCode).ToList();
                            if(a != null && a.Count > 0)
                            {
                                db.Delete<SaleOrderAccount>(it => it.orderCode == goods.orderCode);
                            }
                            db.CommitTran();
                            return true;
                        }else
                        {
                           db.RollbackTran();
                        }
                    }
                }
                catch (Exception ex)
                {
                    db.RollbackTran();
                    logger.Error(ex);
                }
                finally
                {
                    DBLocker.release();
                }
            }
            return false;
        }


        /***
         * 修改单品数量并重新汇算
         * */
        public Boolean changeCount(SaleOrderGoods goods,Double count)
        {
            DBLocker.setLocker();
            using (SqlSugarClient db = SugarDao.GetInstance())
            {
                try
                {
                    db.BeginTran();
                    Boolean b = db.Update<SaleOrderGoods>(new {
                        goodsCount = count,
                        realAmount = Math.Round(count * goods.price,2),
                        payAmount = Math.Round(count * goods.disPrice,2),
                        disAmount = Math.Round( Math.Round(count * goods.price,2) - Math.Round(count * goods.disPrice,2) , 2)
                    },it => it.id == goods.id);

                    if (b)
                    {
                        Int64 result = db.ExecuteCommand(@"UPDATE SaleOrder SET 
		                goodsCount = (select sum(goodsCount) from SaleOrderGoods where orderId = @o1 GROUP BY orderId),
		                realAmount = (select sum(realAmount) from SaleOrderGoods where orderId = @o2 GROUP BY orderId),
		                payAmount = (select sum(payAmount) from SaleOrderGoods where orderId = @o3 GROUP BY orderId),
		                disAmount = (select sum(disAmount) from SaleOrderGoods where orderId = @o4 GROUP BY orderId)
                        WHERE orderId = @o5", new
                        {
                            o1 = goods.orderId,
                            o2 = goods.orderId,
                            o3 = goods.orderId,
                            o4 = goods.orderId,
                            o5 = goods.orderId
                        });
                        if (result > 0)
                        {
                            db.CommitTran();
                            return true;
                        }
                        else
                        {
                            db.RollbackTran();
                        }
                    }
                }
                catch (Exception ex)
                {
                    db.RollbackTran();
                    logger.Error(ex);
                }
                finally
                {
                    DBLocker.release();
                }
            }
            return false;
        }



        /***
         * 修改单品数量并重新汇算
         * */
        public Boolean changePrice(SaleOrderGoods goods, Double disPrice,Cashier authCashier)
        {
            DBLocker.setLocker();
            using (SqlSugarClient db = SugarDao.GetInstance())
            {
                try
                {
                    db.BeginTran();
                    Boolean b = db.Update<SaleOrderGoods>(new
                    {
                        priceSource = GoodsPriceSource.POS.ToString(),
                        disPrice = disPrice,
                        payAmount = Math.Round(goods.goodsCount * disPrice, 2),
                        disAmount = Math.Round(Math.Round(goods.goodsCount * goods.price, 2) - Math.Round(goods.goodsCount * disPrice, 2),2),
                        autherCode = authCashier.cashierCode,
                        autherName = authCashier.cashierName
                    }, it => it.barCode == goods.barCode && it.goodsCode == goods.goodsCode);

                    if (b)
                    {
                        Int64 result = db.ExecuteCommand(@"UPDATE SaleOrder SET 
		                goodsCount = (select sum(goodsCount) from SaleOrderGoods where orderId = @o1 GROUP BY orderId),
		                realAmount = (select sum(realAmount) from SaleOrderGoods where orderId = @o2 GROUP BY orderId),
		                payAmount = (select sum(payAmount) from SaleOrderGoods where orderId = @o3 GROUP BY orderId),
		                disAmount = (select sum(disAmount) from SaleOrderGoods where orderId = @o4 GROUP BY orderId)
                        WHERE orderId = @o5", new
                        {
                            o1 = goods.orderId,
                            o2 = goods.orderId,
                            o3 = goods.orderId,
                            o4 = goods.orderId,
                            o5 = goods.orderId
                        });
                        if (result > 0)
                        {
                            db.CommitTran();
                            return true;
                        }
                        else
                        {
                            db.RollbackTran();
                        }
                    }
                }
                catch (Exception ex)
                {
                    db.RollbackTran();
                    logger.Error(ex);
                }
                finally
                {
                    DBLocker.release();
                }
            }
            return false;
        }

        /**
         * 执行组合促销操作
         * */
        public Boolean doGroupPromotion(SaleOrder order, List<GroupPromotion> proms)
        {
            if(order == null || proms == null || proms.Count <=0)
            {
                return false;
            }
            List<SaleOrderGoods> goods = listCanGroupGoods(order);
            if(goods == null)
            {
                return false;
            }
            DBLocker.setLocker();
            using (SqlSugarClient db = SugarDao.GetInstance())
            {
                try
                {
                    db.BeginTran();
                    Double gCount = 0;
                    foreach (GroupPromotion gp in proms)
                    {
                        foreach (SaleOrderGoods g in goods)
                        {
                            if (gp.barCode.Equals(g.barCode))
                            {
                                gCount = gCount + g.goodsCount;
                            }
                        }
                    }
                    db.CommitTran();
                }
                catch (Exception ex)
                {
                    db.RollbackTran();
                    logger.Error(ex);
                }
                finally
                {
                    DBLocker.release();
                }
            }
            return false;
        }

        public List<SaleOrderGoods> listCanGroupGoods(SaleOrder order)
        {
            DBLocker.setLocker();
            try
            {
                using (SqlSugarClient db = SugarDao.GetInstance())
                {
                    List<SaleOrderGoods> goods = db.Queryable<SaleOrderGoods>()
                        .Where(it => it.orderCode == order.orderCode 
                                && it.priceSource == GoodsPriceSource.NORM.ToString())
                        .ToList();
                    return goods;
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }
            finally
            {
                DBLocker.release();
            }
            return null;
        }
    }
}
